using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace Sedna.Core.Controller.Common
{
    public class GridValidationAction: AbstractGridValidationAction
    {
        private IList gridRowValidators = new ArrayList(0);
        private IList gridValidators = new ArrayList(0);

        public IList GridRowValidators
        {
            set { gridRowValidators = value; }
        }

        public IList GridValidators
        {
            set { gridValidators = value; }
        }

        public override IActionResult Execute(IExecutionContext executionContext)
        {
            IDictionary validationContexts = CreateValidationContexts(gridValidators);
            
            if (TransientData != null && InvalidData != null)
            {
                InvalidData.Clear();
                ErrorMessageKeyData.Clear();
                foreach (Object o in TransientData)
                {
                    ValidateRow(executionContext, validationContexts, o);
                }
            }
            
            foreach (IGridValidator validator in gridValidators)
            {
                AddToErrorMessageKeyData(validator.GetInvalidData(executionContext, validationContexts), validator.ErrorMessageKey);
            }
            
            SetIsValid(executionContext, InvalidData == null || InvalidData.Count == 0);
            return CreateResult(successStatus);
        }

        private IDictionary CreateValidationContexts(IList validators)
        {
            IDictionary contexts = new Hashtable(validators.Count);
            foreach (IGridValidator validator in validators)
            {
                contexts[validator] = new Hashtable();
            }
            return contexts;
        }

        private void ValidateRow(IExecutionContext executionContext, IDictionary validationContexts, object o)
        {
            bool isValid = true;
            foreach (IGridRowValidator validator in gridRowValidators)
            {
                if (!validator.EvaluateIsValid(executionContext, o))
                {
                    isValid = false;
                    AddToErrorMessageKeyData(o, validator.ErrorMessageKey);
                }
            }
            
            foreach (IGridValidator validator in gridValidators)
            {
                validator.AddRow(executionContext, (IDictionary)validationContexts[validator], o);
            }
            
            if (!isValid)
            {
                AddToInvalidData(o);
            }
        }

    }
}
